<?php


include_once( APPPATH . "libraries/sqlparser/sqlParser.php" );


class oNav
{

	var $int_max_rows;			
	var $query;					
	var $completeQuery;
	
	var $db;					
			
	var $string_cur_uri;
	var $cur_sql_pos;
	var $int_tot_rows;
	var $int_tot_page;
	var $int_num_rows_this_page;	
	
	var $layout;					

	var $arr_search_field;			
	
	var $num_nav;				
	var $string_name;			
	var $arr_result;
	var $int_pointer;
	var $is_loaded;				
	var $a;

	function oNav( $string_query, $string_table_id="id", $int_max_rows=10, $int_num_nav="10", $string_name="page"){
		
		$ci =& get_instance();
		
		$this->completeQuery	= $string_query;
		$this->int_max_rows 	= $int_max_rows;
		$this->num_nav 			= $int_num_nav;
		$this->string_name		= $string_name;
		$this->arr_result		= array();
		$this->int_pointer		= 0;
		
		$this->is_loaded['get_data'] 	= false;
		$this->is_loaded['get_array'] = false;

		$this->layout['prev_word']	= "prev";
		$this->layout['next_word']	= "next";
		$this->layout['result']		= "Data ke"; 
		$this->layout['to']			= "s/d";
		$this->layout['of']			= "dari total";
		$this->layout['link_class']	= "";			
		$this->layout['bgcolor'][0]	= "#FFFFFF";	
		$this->layout['bgcolor'][1]	= "";			//contoh :  #787687		
		$this -> setDB( $ci->adodb );
	}
	
	
	function setDB( $db = '' )
	{
		if ( $db == '' )
		{
			global $db;
		}
		$this -> db = $db;
	}

	function setNumMaxRows( $int_max_rows = '10' )
	{
		$this->int_max_rows = $int_max_rows;
	}
		
	function setSearchField( $arr_field )
	{
		$this -> arr_search_field = $arr_field;
	}
	
	function parseQuery()
	{
		
		$result = parseSQL ( $this -> completeQuery );
		
		$result['field']	= getFieldsFromSQL ( $this -> completeQuery );		
		$result['all_after_from']	= $result['tableClause'] . " ". $result['conditionClause'];
		
		$compileResult['all_field'] = $result['field'];
		$compileResult['all_field'] = $result['fieldClause'];
		$compileResult['all_table'] = $result['tableClause'];
		$compileResult['all_where']	= ( !empty( $result['whereClause'] ) ) ? " WHERE ". $result['whereClause'] : "";
		$compileResult['all_order'] = ( !empty( $result['orderbyClause'] ) ) ? " ORDER BY ". $result['orderbyClause'] : "";
		$compileResult['all_limit'] = ( !empty( $result['limitClause'] ) ) ? " LIMIT ". $result['limitClause'] : "";
		$compileResult['distinct'] 	= ( !empty( $result['selectOption'] ) ) ? true : false;
		$compileResult['after_from_no_limit']	= $compileResult['all_table'] ." ". $compileResult['all_where'] ." "
												  . $compileResult['all_order'] ." ";
		$compileResult['all_before_from'] = $result['fieldClause'];
		$this->query	= array_merge( $result, $compileResult );
	}
	
	function getNumAllRows()
	{
		
		if ( !$this->query['distinct'] ) 
		{
			$sql 	= "SELECT count(*) FROM ". $this->query['after_from_no_limit'];
		}
		else
		{
			if ( $this->query['field'][0] != '*' )
			{

				$pos = strpos( $this->query['field'][0], " as ");
				if ( is_integer($pos) ) 
				{
				   $first_field	= substr( $this->query['field'][0], 0, $pos );
				}
				else
				{
					$first_field	= $this->query['field'][0];
				}
				
				$sql 	= "SELECT count( DISTINCT ". $first_field ." ) FROM ". $this->query['after_from_no_limit'];
			}
			elseif ( count($this->query['field']) > 1 )
			{

				$pos = strpos( $this->query['field'][1], " as ");
				if ( is_integer($pos) ) {
				   $first_field	= substr( $this->query['field'][1], 0, $pos );
				}
				else
				{
					$first_field	= $this->query['field'][1];
				}
				
				$sql 	= "SELECT count( DISTINCT ". $first_field ." ) FROM ". $this->query['after_from_no_limit'];
			}
			else
			{
				die("Query menggunakan DISTINCT field yang diselect harus bukan *");
			}
		}

		$result = $this->db->GetOne($sql);
		$num_rows_count = $this->db->Affected_rows();

		if( $num_rows_count == 1 )
		{
			$this->int_tot_rows = $result;
		}
		else
		{
			$this->int_tot_rows = $num_rows_count;
		}

		return $this->int_tot_rows;
	}
	
	function getNumPage()
	{
		return $this->int_tot_page = ceil($this->int_tot_rows / $this->int_max_rows);
	}
	
	function parseUrl()
	{
		$this->string_cur_uri = preg_replace("#\?.*#", "", $_SERVER['REQUEST_URI'])."?";
		if (isset($_GET)) {
			foreach($_GET as $name=>$val) 
			{
				if ($name != $this->string_name)
					$this->string_cur_uri .= $name . "=" . $val ."&";
			}
		}
	}

	function getData()
	{
		if ( isset( $_GET[$this->string_name . "_viewAll"] ) )
		{
			if ( $_GET[$this->string_name . "_viewAll"] == '1' )
			{
				$this->setNumMaxRows( '500' );
				$_GET[$this->string_name]	= '1';
			}
		}
		
		if ( isset( $_GET[$this->string_name] ) )
		{
			if ( $_GET[$this->string_name] != "" )
			{
				$this->int_cur_page = $_GET[$this->string_name];
			}
		}
		else 
			$this->int_cur_page=1;
		
		$this->cur_sql_pos = ($this->int_cur_page-1)*$this->int_max_rows;
		$this -> parseQuery();
		$this -> getNumAllRows();
		$this -> getNumPage();
		$this -> parseUrl();

		$this->is_loaded['get_data'] = true;
	}

	function setPrevNextWord($string_prev_word, $string_next_word )
	{
		$this->layout['prev_word'] = $string_prev_word;
		$this->layout['next_word'] = $string_next_word;
	}
	
	function setLinkClass($string_class)
	{
		$this->layout['link_class'] = $string_class;
	}
	
	function setBgColorA($string_bgcolor)
	{
		$this->layout['bgcolor'][0]	= $string_bgcolor;
	}
	
	function setBgColorB($string_bgcolor)
	{
		$this->layout['bgcolor'][1]	= $string_bgcolor;
	}
	
	function setStatusWord($string_result, $string_to, $string_of )
	{
		$this->layout['result'] = $string_result;
		$this->layout['to'] 	= $string_to;
		$this->layout['of']	 	= $string_of;		
	}
	


	function getPrev()
	{
		$a = '';
		if (!$this->is_loaded['get_data']) $this->getData();
		if ($this->int_cur_page != 1) {
			$int_prev_page = $this->int_cur_page-1;
			if ($this->layout['link_class'] != "") $a = " class=\"". $this->layout['link_class'] ."\"";
			$string_prev = "<li><A $a href=". $this->string_cur_uri . $this->string_name ."=". $int_prev_page .">". $this->layout['prev_word'] ."</a></li>";
			return $string_prev;
		}
		else return("");
	}
	
	function getNext(){
		if (!$this->is_loaded['get_data']) $this->getData();
		if ($this->int_cur_page!=$this->int_tot_page && $this->int_tot_page!=0) {
			$int_next_page = $this->int_cur_page+1;
			if ($this->layout['link_class'] != "") $a = " class=\"". $this->layout['link_class'] ."\"";
			else $a = "";
			$string_next = "<li><A ". $a ." href=". $this->string_cur_uri . $this->string_name ."=". $int_next_page .">". $this->layout['next_word'] ."</a></li>";
			return $string_next;
		}
		else return("");
	}
	
	function getArrNav()
	{
		if (!$this->is_loaded['get_data']) $this->getData();
		$arr_nav = array();
		if ($this->int_tot_page < $this->num_nav) 
			$max = $this->int_tot_page;
		else 
			$max = $this->int_cur_page + $this->num_nav -1;
			
		if ($max > $this->int_tot_page)
			$max = $this->int_tot_page;
		
		if ($max > 2 * $this->num_nav-1 )
			$n = $max - 2 * $this->num_nav;
		else
			$n = 0;
		$k = 0;
		if ($this->layout['link_class'] != "") $a = " class=\"". $this->layout['link_class'] ."\"";
		else $a = "";
		for ($i=$n; $i < $max; $i++) {
			$j = $i+1;
			$arr_nav[$i] = "";
			if ($i<$this->num_nav) $arr_nav[$i].="&nbsp;";
			if ($this->int_cur_page==$j)
				$arr_nav[$i] .= "<li class=\"active\"> ". $a .">$j</li>";
			else 
				$arr_nav[$i] .= "<li><A ". $a ." href=". $this->string_cur_uri . $this->string_name ."=". $j .">". $j ."</A></li>";
			$k++;
		}
		return $arr_nav;
	}
	
	function getNavStatus()
	{
		if (!$this->is_loaded['get_data']) $this->getData();
		$arr_status['begin'] = $this->cur_sql_pos + 1;
		$num_view_rows = $this->cur_sql_pos+$this->int_max_rows;
		$arr_status['end'] = ($num_view_rows < $this->int_tot_rows) ? $num_view_rows : $this->int_tot_rows;
		$arr_status['total'] =  $this->int_tot_rows;
		return $arr_status;
	}
	
	function getNav()
	{
		if (!$this->is_loaded['get_data']) $this->getData();
		$print_nav = "";
		if ($this->int_tot_page > 1) {		
			$prev = $this->getPrev();
			$next = $this->getNext();
			$arr_nav = $this->getArrNav();
			foreach ($arr_nav as $key=>$val)
				$print_nav .= $val ." \n";			
			$print_nav = "<ul>".$prev ." | ". $print_nav ." | ". $next."</ul>";
			return $print_nav;
		}
	}
	
	function getStatus()
	{
		$arr_status = $this->getNavStatus();
		$status	= $this->layout['result'] ." ". $arr_status['begin'];
		$status	.= " ". $this->layout['to'] ." ". $arr_status['end'];
		$status	.= " ". $this->layout['of'] ." ". $arr_status['total'];
		$status	.= " ";
		
		if ( isset( $_POST[$this -> string_name."_search"] ) )
		{
			$status = '';
		}
		return $status;
	}
	

	function getGoToForm( $withFormTag=true ){
		$form	= '';
		if ($this->int_tot_page > 1) {
			$action	= preg_replace("#\?.*#", "", $_SERVER['REQUEST_URI']);
			if ( $withFormTag )
				$form 	.= "\n<form method='get' action='". $action ."' name='".$this->string_name."_goto'>\n";
			$form	.= "Go to Page: ";
			$form	.= "<input type='text' size='2' name='".$this->string_name."' value='$this->int_cur_page' onClick='this.select();' style='text-align:center;'>";
			$form	.= " of $this->int_tot_page ";
			foreach( $_GET as $name=>$val ){
				if ( $name != 'submit' && $name != $this->string_name )
					$form .= "<input type=hidden name=\"$name\" value=\"$val\">\n";
			}
			$form	.= "<input type='submit' value='Go' name=submit>\n";
			if ( $withFormTag )
				$form	.= "\n</form>";
		}
		return $form;
	}
	

	function getViewAllLink( $text_link_tampil = 'Show All',  $text_link_tidak_tampil	= 'Show part' )
	{
		$out	= '';
		if ( $this->int_tot_page > 1  || @$_GET[$this->string_name ."_viewAll"] == '1' ) 
		{
			$string_cur_uri = preg_replace("#\?.*#", "", $_SERVER['REQUEST_URI'])."?";
			if (isset($_GET)) {
				foreach($_GET as $name=>$val) 
				{
					if ($name != $this->string_name ."_viewAll")
						$string_cur_uri .= $name . "=" . $val ."&";
				}
			}
			if ( !isset( $_GET[$this->string_name ."_viewAll"] ) )
			{
				$_GET[$this->string_name ."_viewAll"]	= '0';
			}
			
			if ($this->layout['link_class'] != "") $a = " class=\"". $this->layout['link_class'] ."\"";
			else $a = "";
			
			if ( $_GET[$this->string_name ."_viewAll"] == '1' )
			{
				$out .= "<A ". $a ." href=\"". $string_cur_uri . $this->string_name ."_viewAll" ."=0\" >". $text_link_tidak_tampil ."</A>";
			}
			else
			{
				$out .= "<A ". $a ." href=\"". $string_cur_uri . $this->string_name ."_viewAll" ."=1\" >". $text_link_tampil ."</A>";
			}
		}
		return $out;
	}
	

	function getSearchForm()
	{
		if ( count( $this -> arr_search_field ) == 0 )
			die( "Fatal ERROR: Untuk menggunakan fasilitas search, harus diset dulu field mana yang mau disearch. gunakan method : setSearchField() pada kelas oNav " );
			
		$formName	= "search_form_".$this -> string_name;
		$textName	= $this -> string_name . "_search";
		$form 	= "<form method='post' action='". $this->string_cur_uri ."' name='". $formName ."'>";
		$form	.= "<input type='text' size='5' name='$textName' value='search' onclick=\"$formName.$textName.value=''\" >\n";
		$form	.= "<input type='submit' value='Go'>\n";
		$form	.= "</form>\n";

		return $form;
	}
	

	function getCompleteNav()
	{
		$nav 	= "\n<form method='post' action='". $this->string_cur_uri ."'>\n";
		$nav 	.= $this -> getNav();
		$nav	.= "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
		$nav	.= $this -> getGoToForm( false );
		$nav	.= "<br>" . $this -> getStatus();
		$nav	.= "\n</form>\n";
		return $nav;
	}
	

	function getArrayResult(){
		
		if (!$this->is_loaded['get_data']) $this->getData();

		$sql 	= "SELECT ". $this -> query['all_before_from'] . " FROM ". 
					$this -> query['after_from_no_limit'] ." LIMIT ". $this->cur_sql_pos .", ". $this->int_max_rows;
		
		if ( isset( $_POST[$this -> string_name."_search"] ) )
		{
			$sql = $this > getSearchSqlQuery();
		}
		$result	= $this -> db -> getAll( $sql );
		$this->int_num_rows_this_page	= $this->db->Affected_rows();
		
		$this->arr_result				= $result;
		$this->is_loaded['get_array']	= true;
	}
	
	function fetch(){
		if (!$this->is_loaded['get_array']) $this->getArrayResult();
		if ($this->int_pointer < $this->int_num_rows_this_page){
			$pointer	= $this->int_pointer;
			$this->int_pointer++;
			if ($this->layout['bgcolor'][1] == "") $c = $this->layout['bgcolor'][0];
			else {
				$c = $this->layout['bgcolor'][0];
				$this->layout['bgcolor'][0]	= $this->layout['bgcolor'][1];
				$this->layout['bgcolor'][1]	= $c;
			}
			$this->arr_result[$pointer]['bgcolor'] = $c;
			return $this->arr_result[$pointer];
		}
		else
		{ 
			return false;
		}
	}
}
?>
